/*

2020.12.12 周六制作

  运用知识点有：struct结构体、函数指针、循环、数组等。
  实现功能：对其学生的数学、英语、语文、物理、化学、物理以及姓名和学号排序。

2020.12.13 周日更新

  更新功能：新加升序降序。

2020.12.17 周四更新

  优化程序。
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define stuNumber 5
char NAME[stuNumber][15]={{"Jeff"},{"Mali"},{"Zhang san"},{"Li si"},{"Liu ming"}};
char SEX[stuNumber][2]={{"M"},{"F"},{"M"},{"M"},{"F"}};
struct Score{
	int Math;
	int English;
	int Chinese;
	int Physical;
	int Chemical;
	int Biological;
};
struct student{
	char name[15];
	char sex[3];
	struct Score score;
	long stuID;
};
int main()
{
    void NameSort(struct student Stu[],char);
    void ScoreMathSort(struct student Stu[],char);
   	void ScoreEnglishSort(struct student Stu[],char);
   	void ScoreChineseSort(struct student Stu[],char);
   	void ScorePhysicalSort(struct student Stu[],char);
   	void ScoreChemicalSort(struct student Stu[],char);
	void ScoreBiologicalSort(struct student Stu[],char);
    void pointStudent(struct student Stu[]);
	void inputStudent(struct student Stu[]);
	char get_choiceLH();//Del \n
    int get_choice();
	int i,j=0;
	int choice;
	char choiceLH;
	struct student Stu[stuNumber];//创建学生结构体变量
	inputStudent(Stu);//录入学生信息随机成绩
	printf("Initialize Student：\n");
	pointStudent(Stu);//打印原数据
	choice = get_choice();//获取1~8的命令
	while(choice!=8)
	{
		choiceLH = get_choiceLH();//获取L&H
		switch (choice)
		{
			case 1:NameSort(Stu,choiceLH);break;
			case 2:ScoreMathSort(Stu,choiceLH);break;
			case 3:ScoreEnglishSort(Stu,choiceLH);break;
			case 4:ScoreChineseSort(Stu,choiceLH);break;
			case 5:ScorePhysicalSort(Stu,choiceLH);break;
			case 6:ScoreChemicalSort(Stu,choiceLH);break;
			case 7:ScoreBiologicalSort(Stu,choiceLH);break;
			default:printf("input error!Please re-enter:");break;
		}
		choice = get_choice();//获取1~8的命令
	}
	printf("\n\tThanks!\t\n\n");
	return 0;
}
void NameSort(struct student Stu[],char n)//selectionSort(选择排序)
{
	void pointStudent(struct student Stu[]);
	int i,j,k;
	struct student temp;
	for(i=0;i<stuNumber-1;i++)
	{
		k=i;
		for(j=i+1;j<stuNumber;j++)
		{
			if(strcmp(Stu[j].name,Stu[k].name)>0 && n=='H') 
				k=j;
			else if(strcmp(Stu[j].name,Stu[k].name)<0 && n=='L')
				k=j;
		}
		if(k!=i)
		{
			temp=Stu[i];
			Stu[i]=Stu[k];
			Stu[k]=temp;
		}
	}
	printf("\nNameSort:\n");
	pointStudent(Stu);
}
void ScoreMathSort(struct student Stu[],char n)//bubbleSort(冒泡排序)
{
	void pointStudent(struct student Stu[]);
	struct student temp;
	int i,j;
	for(i=0;i<stuNumber-1;i++)
	{
		for(j=0;j<stuNumber-1-i;j++)
		{
			if (Stu[j].score.Math > Stu[j+1].score.Math && n=='H')
			{
				temp=Stu[j];
				Stu[j]=Stu[j+1];
				Stu[j+1]=temp;
			}else if(Stu[j].score.Math < Stu[j+1].score.Math && n=='L')
			{
				temp=Stu[j];
				Stu[j]=Stu[j+1];
				Stu[j+1]=temp;
			}
		}
	}
	printf("\nScoreMathSort:\n");
	pointStudent(Stu);
}
void ScoreEnglishSort(struct student Stu[],char n)//insertionSort(插入排序)
{
	void pointStudent(struct student Stu[]);
	struct student current;
	int preIndex,i;
	for(i=1;i<stuNumber;i++)
	{
		preIndex=i-1;
		current=Stu[i];
		while(preIndex>=0 && Stu[preIndex].score.English > current.score.English && n=='H')
		{
			Stu[preIndex+1]=Stu[preIndex];
			preIndex--;
		}
		while(preIndex>=0 && Stu[preIndex].score.English < current.score.English && n=='L')
		{
			Stu[preIndex+1]=Stu[preIndex];
			preIndex--;
		}
		Stu[preIndex+1]=current;
	}
	printf("\nScoreEnglishSort:\n");
	pointStudent(Stu);
}
void ScoreChineseSort(struct student Stu[],char n)//shellSort(希尔排序)
{
	void pointStudent(struct student Stu[]);
	struct student current;
	int i,gap,j;
	for (gap=stuNumber/2;gap>0;gap=gap/2)
	{
		for (i=gap;i<stuNumber;i++)
		{
			j=i;
			current=Stu[i];
			while (j-gap>=0 && current.score.Chinese < Stu[j-gap].score.Chinese && n=='H')
			{
				Stu[j]=Stu[j-gap];
				j=j-gap;
			}
			while (j-gap>=0 && current.score.Chinese > Stu[j-gap].score.Chinese && n=='L')
			{
				Stu[j]=Stu[j-gap];
				j=j-gap;
			}
			Stu[j]=current;
		}
	}
	printf("\nScoreChineseSort:\n");
	pointStudent(Stu);
}
void ScorePhysicalSort(struct student Stu[],char n)
{
	void pointStudent(struct student Stu[]);
	int i,j,k;
	struct student temp;
	for(i=0;i<stuNumber-1;i++)
	{
		k=i;
		for(j=i+1;j<stuNumber;j++)
		{
			if(Stu[j].score.Physical < Stu[k].score.Physical && n=='H') 
				k=j;
			else if(Stu[j].score.Physical > Stu[k].score.Physical && n=='L')
				k=j;
		}
			if(k!=i)
			{
				temp=Stu[i];
				Stu[i]=Stu[k];
				Stu[k]=temp;
			}
	}
	printf("\nScorePhysicalSort:\n");
	pointStudent(Stu);
}
void ScoreChemicalSort(struct student Stu[],char n)
{
	void pointStudent(struct student Stu[]);
	int i,j,k;
	struct student temp;
	for(i=0;i<stuNumber-1;i++)
	{
		k=i;
		for(j=i+1;j<stuNumber;j++)
		{
			if(Stu[j].score.Chemical < Stu[k].score.Chemical && n=='H') 
				k=j;
			else if(Stu[j].score.Chemical > Stu[k].score.Chemical && n=='L')
				k=j;
		}
			if(k!=i)
			{
				temp=Stu[i];
				Stu[i]=Stu[k];
				Stu[k]=temp;
			}
	}
	printf("\nScoreChemicalSort:\n");
	pointStudent(Stu);
}
void ScoreBiologicalSort(struct student Stu[],char n)
{
	void pointStudent(struct student Stu[]);
	int i,j,k;
	struct student temp;
	for(i=0;i<stuNumber-1;i++)
	{
		k=i;
		for(j=i+1;j<stuNumber;j++)
		{
			if(Stu[j].score.Biological < Stu[k].score.Biological && n=='H') 
				k=j;
			else if(Stu[j].score.Biological > Stu[k].score.Biological && n=='L')
				k=j;
		}
			if(k!=i)
			{
				temp=Stu[i];
				Stu[i]=Stu[k];
				Stu[k]=temp;
			}
	}
	printf("\nScoreBiologicalSort:\n");
	pointStudent(Stu);
}
int get_first()//Del \n
{
	int ch;
	ch=getchar();
	while(ch == '\n')
	{
		ch=getchar();
	}
	return ch;
}
char get_LorH()//Del \n
{
	char ch;
	ch=getchar();
	while(ch == '\n')
	{
		ch=getchar();
	}
	return ch;
}
char get_choiceLH()
{
	char n;
	printf("\nPlease Input L&H (L->降序||H->升序):");
	n=get_LorH();
	while(n == ' ' || n == '\n' || n == '\t'){
		n = get_LorH();
	}
	while(n !='L' && n!='H')
	{
		printf("input error!Please re-enter:");
		n=get_LorH();
	}
	printf("%c\n\n",n);
	return n;
}
int get_choice()
{
	char ch;
	printf("\n\t---------------------------------------------------\n");
	printf("\t|a.NameSort: 1\t            b.ScoreMathSort: 2    |\n\t|c.ScoreEnglishSort: 3\t    d.ScoreChineseSort: 4 |\n\t|e.ScorePhtsicalSort: 5\t    f.ScoreChemicalSort: 6|\n\t|g.ScoreBiologicalSort: 7   h.END: 8              |\n\t");
	printf("---------------------------------------------------\n");
    printf("Please enter your choice:");
	ch=get_first();
	while(ch == ' ' || ch == '\n' || ch == '\t'){
		ch = get_first();
	}
	while((ch<'0' || ch>'9') && ch !='8')
	{
		printf("input error!Please re-enter:");
		ch=get_first();
	}
	return ch-'0';
}
void pointStudent(struct student Stu[])//point
{
	int i;
	printf("StudentID\tName\tSex\tMathscore\tEnglishscore\tChineseSroce\tPhtsicalScore\tChemicalScore\tBiologicalScore\n");
	for(i=0;i<stuNumber;i++)
		printf("%7d %13s %3s %12d %15d %15d %15d %15d %16d\n",Stu[i].stuID,Stu[i].name,Stu[i].sex,Stu[i].score.Math,Stu[i].score.English,Stu[i].score.Chinese,Stu[i].score.Physical,Stu[i].score.Chemical,Stu[i].score.Biological);
}
void inputStudent(struct student Stu[])
{
	int i;
	for(i=0;i<stuNumber;i++)
	{
		strcpy(Stu[i].name,NAME[i]);
		strcpy(Stu[i].sex,SEX[i]);
	}
	for(i=0;i<stuNumber;i++)
	{
		Stu[i].score.Math=rand()%65+86;
		Stu[i].score.English=rand()%90+61;
		Stu[i].score.Chinese=rand()%90+61;
		Stu[i].score.Physical=rand()%35+76;
		Stu[i].score.Chemical=rand()%34+67;
		Stu[i].score.Biological=rand()%35+56;
		Stu[i].stuID=10100+i+1;
	}//initialize student
}
